﻿using Autofac;
using MgSoft.K3Cloud.WebApi.Dto;
using MgSoft.K3Cloud.WebApi.Exceptions;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace MgSoft.K3Cloud.WebApi
{
    /// <summary>
    /// 金蝶连接信息缓存服务
    /// </summary>
    public class KingdeeClientInfoMemoryService
    {
        /// <summary>
        /// 容器生命周期对象
        /// </summary>
        public ILifetimeScope lifetimeScope { get; set; }
        ApiServerInfo apiServerInfo => lifetimeScope.Resolve<ApiServerInfo>();
        /// <summary>
        /// 金蝶接口定义
        /// </summary>
        public K3CloudApiExecuter k3CloudClient { get; set; }
        /// <summary>
        /// 锁对象
        /// </summary>
        readonly object iLock = new object();

        public K3CloudClientInfo Get()
        {
            lock (iLock)
            {
                var k3CloudClientInfo = lifetimeScope.Resolve<K3CloudClientInfo>();

                var milliSecond = (DateTime.Now - k3CloudClientInfo.LoginSuccessTime)?.TotalMilliseconds ?? -1;
                if (milliSecond > 5 * 60 * 1000) //五分钟
                {
                    k3CloudClient.Logout(k3CloudClientInfo);
                    k3CloudClientInfo = new K3CloudClientInfo(apiServerInfo);
                    loginK3Cloud(k3CloudClientInfo);
                }
                else if (milliSecond == -1) 
                {
                    /*
                     * 由于 K3CloudClientInfo 对象的注入形式是单例的，所以当这个对象第一次被初始化的时候应该所有信息都是空的；
                     * 目前遇到的一个案例是，K3CloudClientInfo的信息不是通过ApiServerInfo(读取登录信息文件)来获取，而是由界面录入，
                     * 所以通过LoginSuccessTime属性来判断是否登录过。通过UserName来判断是否已经被编辑过，如果没被编辑过，则通过ApiServerInfo构建基本信息。否则使用现有信息进行登录校验。
                     */
                    if (string.IsNullOrWhiteSpace(k3CloudClientInfo.UserName)) k3CloudClientInfo = new K3CloudClientInfo(apiServerInfo);
                    loginK3Cloud(k3CloudClientInfo);
                }

                return k3CloudClientInfo;
            }
        }

        private void loginK3Cloud(K3CloudClientInfo k3CloudClientInfo)
        {
            var validateUserResult = k3CloudClient.ValidateUser(k3CloudClientInfo);
            checkValidateUser(validateUserResult);
            k3CloudClientInfo.LoginSuccessTime = DateTime.Now;
            
            var cookiesCollection = k3CloudClient.kingdeeHttpClient.Cookie.GetCookies(new Uri(k3CloudClientInfo.ServerUrl));
            if ((cookiesCollection?.Count ?? 0) > 0)
            {
                k3CloudClientInfo.kdservice_sessionid = cookiesCollection["kdservice-sessionid"].Value;
                k3CloudClientInfo.ASP_NET_SessionId = cookiesCollection["ASP.NET_SessionId"].Value;
            }
        }

        private void checkValidateUser(string validateUserResult)
        {
            var resultType = JObject.Parse(validateUserResult)["LoginResultType"].Value<int>();

            if (resultType != 1)
            {
                var msg = JObject.Parse(validateUserResult)["Message"].Value<string>();
                throw new KingdeeLogInException(msg);
            }
        }
    }
}
